package models

import (
	"cloudops/src/config"
	"fmt"
	"github.com/gammazero/workerpool"
	"go.uber.org/zap"
)

func MockCmdbTree(sc *config.ServerConfig) {

	// cmdb测试
	sc.Logger.Info("创建2个固定的节点")
	mockEcsK8sMaster01 := &ResourceEcs{}
	mockEcsK8sMaster01.IpAddr = "192.168.101.23"
	mockEcsK8sMaster01.InstanceName = "cloudops"
	mockEcsK8sMaster01.InstanceId = "cloudops-id"
	mockEcsK8sMaster01.Hostname = "cloudops"
	mockEcsK8sMaster01.OSName = "ubuntu"
	mockEcsK8sMaster01.Hash = mockEcsK8sMaster01.GenHash()
	mockEcsK8sMaster01.Cpu = 2
	mockEcsK8sMaster01.Memory = 4
	mockEcsK8sMaster01.VmType = 2

	mockEcsK8sIngress01 := &ResourceEcs{}
	mockEcsK8sIngress01.IpAddr = "192.168.101.24"
	mockEcsK8sIngress01.InstanceName = "node1"
	mockEcsK8sIngress01.InstanceId = "node1-id"
	mockEcsK8sIngress01.Hostname = "node1"
	mockEcsK8sIngress01.OSName = "ubuntu"
	mockEcsK8sIngress01.Hash = mockEcsK8sIngress01.GenHash()
	mockEcsK8sIngress01.Cpu = 2
	mockEcsK8sIngress01.Memory = 4
	mockEcsK8sIngress01.VmType = 2

	ecss := []*ResourceEcs{
		mockEcsK8sMaster01,
		mockEcsK8sIngress01,
	}
	for _, ecs := range ecss {
		ecs := ecs
		err := ecs.CreateOrUpdate()
		if err != nil {
			sc.Logger.Error("创建固定的ecs错误", zap.Error(err))
		}

	}
	sc.Logger.Info("完成创建2个固定的节点")
	// 查询ecs
	//ecss, err := GetResourceEcsAll()
	// 在这里我们不需要bindnodes 直接替换就行
	ecss, err := GetResourceEcsAllNoPreload()
	sc.Logger.Info("完成查询所有ecs")
	// 服务树
	streeNodes := []*StreeNode{
		{
			Title: "tencent",
			Desc:  "腾讯总部",
			Pid:   0,
			Level: 1,
			OpsAdmins: []*User{
				&u1, &u2,
			},
		},
		{
			Title: "IEG",
			Desc:  "腾讯-腾讯互动娱乐",
			Pid:   1,
			Level: 2,
			OpsAdmins: []*User{
				&u1, &u2,
			},
		},
		{
			Title: "WXG",
			Desc:  "微信事业群",
			Pid:   1,
			Level: 2,
		},
		{
			Title: "Game",
			Pid:   2,
			Level: 3,
			Desc:  "全球领先的综合互动娱乐服务品牌，为用户提供多元化、高品质的数字内容体验",
		},
		{
			Title: "CF",
			Pid:   4,
			Level: 4,
			Desc:  "十亿人的枪战梦想",
		},
		{
			Title:  "king",
			Pid:    4,
			Level:  4,
			Desc:   "王者荣耀",
			IsLeaf: true,
			RdAdmins: []*User{
				&u1, &u2,
			},
		},
		{
			Title: "chiji",
			Pid:   4,
			Level: 4,
			Desc:  "吃鸡模式",
		},
		{
			Title:  "xiangzhan",
			Pid:    5,
			Level:  4,
			Desc:   "巷战模式",
			IsLeaf: true,
			RdAdmins: []*User{
				&u1, &u2,
			},
		},
		{
			Title: "pay",
			Pid:   3,
			Level: 3,
			Desc:  "微信支付 每天多少单",
		},
		{
			Title: "quan",
			Pid:   3,
			Level: 3,
			Desc:  "朋友圈 用来装X",
		},
		{
			Title: "ads",
			Pid:   10,
			Level: 4,
			Desc:  "广告服务",
		},
		{
			Title: "share",
			Pid:   10,
			Level: 4,
			Desc:  "转发",
		},
		{
			Title:  "TEG",
			Pid:    1,
			Level:  2,
			Desc:   "测试叶子节点",
			IsLeaf: true,
		},
		{
			Title:  "jiangshi",
			Pid:    5,
			Level:  4,
			Desc:   "僵尸模式",
			IsLeaf: true,
		},
		{
			Title:  "daozhan",
			Pid:    5,
			Level:  4,
			Desc:   "刀战模式",
			IsLeaf: true,
		},
	}

	sc.Logger.Info("开始创建服务树节点")
	for _, obj := range streeNodes {
		obj := obj
		err = obj.FirstOrCreate()
		if err != nil {
			sc.Logger.Error("创建服务树节点错误", zap.Error(err))
		}
	}
	sc.Logger.Info("结束创建服务树节点")

	sc.Logger.Info("获取所有的叶子节点")
	// 获取所有的叶子节点
	allLeafNodes, err := GetStreeNodeAllLeafSimple()
	if err != nil {
		sc.Logger.Error("获取所有的叶子节点错误", zap.Error(err))
		return
	}

	num := len(allLeafNodes)
	if num == 0 {
		return
	}

	// 绑定的方法 ：2种
	// 1. 给树节点绑定ecs列表
	// 2. 给ecs绑定树节点
	upFuncEcs := func(es []*ResourceEcs, node *StreeNode) {

		wp := workerpool.New(50)
		for _, dbResource := range es {
			dbResource := dbResource
			thisNodes := []*StreeNode{}
			tmpM := map[uint]*StreeNode{}
			for _, node := range dbResource.BindNodes {
				node := node
				tmpM[node.ID] = node
			}
			tmpM[node.ID] = node
			for _, node := range tmpM {
				node := node
				thisNodes = append(thisNodes, node)
			}
			wp.Submit(func() {
				err = dbResource.UpdateBindNodes(thisNodes)
			})
			// 更新这个资源的 bindnodes
		}
		wp.StopWait()

	}

	upFuncNode := func(es []*ResourceEcs, node *StreeNode) {
		// 1. 给树节点绑定ecs列表
		pageSize := 100
		num := len(es) / pageSize
		currentPage := 1
		for currentPage <= num {
			startIndex := (pageSize) * (currentPage - 1)
			endIndex := startIndex + pageSize

			if endIndex > len(es) {
				endIndex = len(es)
			}
			tmp := es[startIndex:endIndex]
			err := node.UpdateBindNodes(tmp)
			if err != nil {
				sc.Logger.Error("给树节点绑定ecs列表错误",
					zap.Any("树节点", node.NodePath),
					zap.Error(err),
				)
			}
			currentPage++
		}

	}
	fmt.Println(upFuncEcs, upFuncNode)

	// 允许 1个资源绑定到多个节点下
	// 按照0.1*5的比例去放大
	sc.Logger.Info("结束获取所有的叶子节点")
	sc.Logger.Info("开始给服务树节点绑定ecs")
	num = len(ecss)
	if num > 2000 {
		num = 2000
	}
	upFuncEcs(ecss[:num], allLeafNodes[0])
	sc.Logger.Info("结束给服务树节点绑定ecs")
}
